package common

import (
	"fmt"

	"github.com/golang/protobuf/proto"
	pbcom "hundsun.com/hsl/hschain/protos/common"
	"hundsun.com/hsl/hschain/protos/config"
	"hundsun.com/hsl/hschain/protos/manage"
	"hundsun.com/hsl/hschain/store/db"
)

const (
	mainBoard      = "main.bd"
	consensusOp    = "consensus.op"
	consensusBoard = "consensus.bd"
	certOp         = "cert.op"
	certBoard      = "cert.bd"
	sysParamOp     = "sysParam.op"
	sysParamBoard  = "sysParam.bd"
	paraChainOp    = "paraChain.op"
	paraChainBoard = "paraChain.bd"
	generalOp      = "general.op"
)

func getGroupDesc(opType manage.UserGroupType) string {
	switch opType {
	case manage.UserGroupType_MainBoard:
		return mainBoard
	case manage.UserGroupType_ConsensusOperator:
		return consensusOp
	case manage.UserGroupType_CertsOperator:
		return certOp
	case manage.UserGroupType_SysParamOperator:
		return sysParamOp
	case manage.UserGroupType_ParaChainOperator:
		return paraChainOp
	case manage.UserGroupType_GeneralOperator:
		return generalOp
	case manage.UserGroupType_ConsensusBoard:
		return consensusBoard
	case manage.UserGroupType_CertsBoard:
		return certBoard
	case manage.UserGroupType_SysParamBoard:
		return sysParamBoard
	case manage.UserGroupType_ParaChainBoard:
		return paraChainBoard
	default:
		return ""
	}
}

// GenGroupInfoKey 生成用户组信息Key
func GenGroupInfoKey(groupType manage.UserGroupType) []byte {
	groupDesc := getGroupDesc(groupType)
	return []byte(db.NamespaceManageFlowGroupInfo + groupDesc)
}

// GenMainBoardKey 生成主委员会Key
func GenMainBoardKey() []byte {
	return []byte(db.NamespaceManageFlowGroupInfo + mainBoard)
}

// UserGroupKV 生成用户组KV
func UserGroupKV(groupType manage.UserGroupType, group *manage.ManageFlowValidatorInfo) (*pbcom.KeyValue, error) {
	var kv = &pbcom.KeyValue{}
	kv.Key = GenGroupInfoKey(groupType)
	groupInfo, err := proto.Marshal(group)
	if err != nil {
		return nil, err
	}
	kv.Value = groupInfo
	return kv, nil
}

// MainBoardKV 主委员会KV
func MainBoardKV(group *manage.ManageFlowValidatorInfo) (*pbcom.KeyValue, error) {
	return UserGroupKV(manage.UserGroupType_MainBoard, group)
}

// VoteHistoryKV 历史投票KV
func VoteHistoryKV(flowID uint32, validators *manage.ManageFlowValidatorInfo) (*pbcom.KeyValue, error) {
	var kv = &pbcom.KeyValue{}
	kv.Key = GenVoteHistoryKey(flowID)
	validatorInfo, err := proto.Marshal(validators)
	if err != nil {
		return nil, err
	}
	kv.Value = validatorInfo
	return kv, nil
}

// GenVoteHistoryKey 历史投票Key
func GenVoteHistoryKey(flowID uint32) []byte {
	return []byte(db.NamespaceManageFlowGroupInfo + fmt.Sprintf("%d", flowID))
}

// SysParamKV 共识配置提案KV
func SysParamKV(param *config.StepSysParam) (*pbcom.KeyValue, error) {
	var kv = &pbcom.KeyValue{}
	kv.Key = GenSysParamKey()
	sysParamInfo, err := proto.Marshal(param)
	if err != nil {
		return nil, err
	}
	kv.Value = sysParamInfo
	return kv, nil
}

// GenSysParamKey 共识配置Key
func GenSysParamKey() []byte {
	return []byte(db.NamespaceSystemParam + "comm")
}

// ConsensusParamKV 共识配置提案KV
func ConsensusParamKV(param *config.StepConParam) (*pbcom.KeyValue, error) {
	var kv = &pbcom.KeyValue{}
	kv.Key = GenConsensusParamKey()
	consensusParamInfo, err := proto.Marshal(param)
	if err != nil {
		return nil, err
	}
	kv.Value = consensusParamInfo
	return kv, nil
}

// GenConsensusParamKey 共识配置Key
func GenConsensusParamKey() []byte {
	return []byte(db.NamespaceSystemParam + "consensus")
}
